package juego;

import java.util.ArrayList;
import java.util.Iterator;

import vista.VistaTripulado;
import ar.uba.fi.algo3.titiritero.Dibujable;

public class Tripulado extends Movil {

	
	//atributos de clase
	private static int miOrigenEnX = 170;//10;
	private static int miOrigenEnY = 350;// 0;
	private static int miResistenciaMaxima = 30;
	public static int miTamanio = 3;
	private static int miVelocidad = 15;
	private static int miImpacto = 10;
	private static int miCapacidadArmamento = 3;
	
	
	//atributos de instancia
	private Energia resistencia;
	private Disparable armamento[]; 	
	private int cantidadArmas;
	//metodos
	
	//constructor. siempre tiene la misma ubicacion inicial
	public Tripulado() {
		super (miOrigenEnX, miOrigenEnY);
		this.resistencia = new Energia (miResistenciaMaxima);
		this.armamento = new Disparable[miCapacidadArmamento];
		this.armamento[0] = new ArmaLaser();
		this.cantidadArmas = 1;
	};
	
	//Devuelve el impacto provocado
    @Override
	public Impacto impactoProvocado(){
		return new ImpactoLineal(miImpacto);
	};   

	@Override
	public boolean esNaveEnemiga() {
		return false;
	};

	@Override
	public boolean esProyectil() {
		return false;
	};

	@Override
	public boolean verLealtad(){
		return true;
	};
	
	@Override
	public int verTamanio(){
		return miTamanio;
	};

	public void recargarEnergia(int mejora) {
		this.resistencia.incrementarEnergia(mejora);
	};
	
	//crea una nueva ArmaCohete y ArmaTorpedoRastreador
	//y los posiciona donde estaban los mismos previamente. 
	public void recargarArmamento(){
		this.armamento[1] = new ArmaCohete();
		this.armamento[2] = new ArmaTorpedoRastreador();
		this.cantidadArmas = 3;
	}
	
	public int verResistencia(){
		return this.resistencia.verEnergia();
	};
	
		
		
	
	//recibe la lista de moviles y la de botines. devuelve el puntaje
	//lanza una ExcepcionMuerto
	public int vivir(ArrayList<Movil> listaDeMoviles,
			ArrayList<Botin> listaDeBotines){
		
		if(!this.vivo){
			throw new ExcepcionMuerto();
		};
		
		int puntaje = this.impactar(listaDeMoviles, listaDeBotines);
		this.recuperarBotin(listaDeBotines);
		return puntaje;
	}
	
	//se encarga de recorrer la lista de botines y utilizar los que encuentre
	private void recuperarBotin(ArrayList<Botin> listaDeBotines) {
		
		Iterator<Botin> iterador = listaDeBotines.iterator();
		while (iterador.hasNext()){
			Botin botin = iterador.next();
			try{
				if (botin.huboContacto(this)){
					botin.mejorar(this);
					iterador.remove();
				}
			}
			catch (Exception e){};
		}
	};
				
	//recibe la lista de moviles
	//agrega nuevos proyectiles a lista de moviles
	//si esta muerto, lanza una ExcepcionMuerto
	

	public ArrayList<Movil> disparar(){
		if(!this.vivo){
			throw new ExcepcionMuerto();
		};
		
		int lugarDisparo = 0;
		Coordenada lugar;
		int lugarX = this.ubicacion.obtenerCoordenadaX();
		int lugarY = this.ubicacion.obtenerCoordenadaY();
		int indice = 0;
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		while (indice < this.cantidadArmas){
			try{
				lugar = new Coordenada(lugarX + lugarDisparo, lugarY);
				Proyectil proyectil = this.armamento[indice].disparar(lugar);
				proyectil.hacerLeal();
				listaDeMoviles.add(proyectil);
				lugarDisparo++;
			}
			catch(Exception e){}
			indice++;
		}
		return listaDeMoviles;
	}
	
	
	//Retorna el puntaje acumulado por la destruccion de otros moviles.
	//Este metodo se encarga de llamar al metodo destruirse.
	@Override
	protected int impactar(ArrayList<Movil> listaDeMoviles, 
			ArrayList<Botin> listaDeBotines){
		int puntaje = 0;
		Iterator<Movil> iterador = listaDeMoviles.iterator();
		boolean contacto;
				
		while (iterador.hasNext()){
			
			Movil movil = iterador.next();
			try {
				contacto = movil.huboContacto(this);
				
				if (contacto & !movil.verLealtad()){
					
					//recibe el impacto
					movil.impactoProvocado().herir(this.resistencia);
										
					//provoca el impacto
					puntaje += movil.recibirImpacto(this.impactoProvocado(), listaDeMoviles, listaDeBotines);
					
					//si no esta vivo lo elimina de la lista
					if (!movil.estaVivo()){
						iterador.remove();
					};
				}
			}
			catch (Exception e){}
		}
		
		if (!this.resistencia.quedaEnergia()){
			this.destruirse(listaDeMoviles);
		}
		
		return puntaje;
	};
	
		
	@Override
	public int recibirImpacto(Impacto danio, ArrayList<Movil> listaDeMoviles,
			ArrayList<Botin> listaDeBotines){
		danio.herir(this.resistencia);
		
		if (!resistencia.quedaEnergia()){
			this.vivo = false;
		};
		
		return 0;
	}

	
	public void moverEnXPositivo(){
        this.ubicacion.moverEnX(miVelocidad);
	}
	
	public void moverEnXNegativo(){
        this.ubicacion.moverEnX(-miVelocidad);
	}

	public void moverEnYNegativo(){
        this.ubicacion.moverEnY(-miVelocidad);
	}
	
	public void moverEnYPositivo(){
        this.ubicacion.moverEnY(miVelocidad);
	}
	
	@Override
	public Dibujable getDibujable() {
		Dibujable dibujable = new VistaTripulado();
		dibujable.setPosicionable(this);
		return dibujable;
	};

	
	
	

	

}
